{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Qiskit Gradient Framework\n",
    "\n",
    "The gradient framework enables the evaluation of quantum gradients as well as functions thereof.\n",
    "Besides standard first order gradients of expectation values of the form\n",
    "$$ \\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle $$\n",
    "<!--- $$ \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta} $$\n",
    "\n",
    "$$ \\frac{\\partial^2\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta^2}, $$\n",
    "--->\n",
    "\n",
    "The gradient framework also supports the evaluation of second order gradients (Hessians), and the Quantum Fisher Information (QFI) of quantum states $|\\psi\\left(\\theta\\right)\\rangle$."
   ]
  },
  {
   "attachments": {
    "gradient_framework.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![gradient_framework.png](attachment:gradient_framework.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "#General imports\n",
    "import numpy as np\n",
    "\n",
    "#Operator Imports\n",
    "from qiskit.opflow import Z, X, I, StateFn, CircuitStateFn, SummedOp\n",
    "from qiskit.opflow.gradients import Gradient, NaturalGradient, QFI, Hessian\n",
    "\n",
    "#Circuit imports\n",
    "from qiskit.circuit import QuantumCircuit, QuantumRegister, Parameter, ParameterVector, ParameterExpression\n",
    "from qiskit.circuit.library import EfficientSU2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## First Order Gradients\n",
    "\n",
    "\n",
    "Given a parameterized quantum state $|\\psi\\left(\\theta\\right)\\rangle = V\\left(\\theta\\right)|\\psi\\rangle$ with input state $|\\psi\\rangle$, parametrized Ansatz $V\\left(\\theta\\right)$, and observable $\\hat{O}\\left(\\omega\\right)=\\sum_{i}\\omega_i\\hat{O}_i$, we want to compute..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Gradients w.r.t. Measurement Operator Parameters\n",
    "\n",
    "Gradient of an expectation value w.r.t. a coefficient of the measurement operator respectively observable $\\hat{O}\\left(\\omega\\right)$, i.e.\n",
    "$$ \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\omega_i} = \\langle\\psi\\left(\\theta\\right)|\\hat{O}_i\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle. $$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First of all, we define a quantum state $|\\psi\\left(\\theta\\right)\\rangle$ and a Hamiltonian $H$ acting as observable. Then, the state and the Hamiltonian are wrapped into an object defining the expectation value $$ \\langle\\psi\\left(\\theta\\right)|H|\\psi\\left(\\theta\\right)\\rangle. $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ComposedOp([\n",
      "  OperatorMeasurement(2.0 * X\n",
      "  + 1.0 * Z),\n",
      "  CircuitStateFn(\n",
      "        ┌───┐┌───────┐┌───────┐\n",
      "  q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b) ├\n",
      "        └───┘└───────┘└───────┘\n",
      "  )\n",
      "])\n"
     ]
    }
   ],
   "source": [
    "# Instantiate the quantum state\n",
    "a = Parameter('a')\n",
    "b = Parameter('b')\n",
    "q = QuantumRegister(1)\n",
    "qc = QuantumCircuit(q)\n",
    "qc.h(q)\n",
    "qc.rz(a, q[0])\n",
    "qc.rx(b, q[0])\n",
    "\n",
    "# Instantiate the Hamiltonian observable\n",
    "H = (2 * X) + Z\n",
    "\n",
    "# Combine the Hamiltonian observable and the state\n",
    "op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)\n",
    "\n",
    "# Print the operator corresponding to the expectation value\n",
    "print(op)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We construct a list of the parameters for which we aim to evaluate the gradient.\n",
    "Now, this list and the expectation value operator are used to generate the operator which represents the gradient."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": false,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ListOp([\n",
      "  SummedOp([\n",
      "    ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└─────────────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -1.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└─────────────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├\n",
      "            └───┘└─────────────────────────┘└───────┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├\n",
      "            └───┘└─────────────────────────┘└───────┘\n",
      "      )\n",
      "    ])\n",
      "  ]),\n",
      "  SummedOp([\n",
      "    ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├┤ H ├\n",
      "            └───┘└───────┘└─────────────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -1.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├┤ H ├\n",
      "            └───┘└───────┘└─────────────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├\n",
      "            └───┘└───────┘└─────────────────────────┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├\n",
      "            └───┘└───────┘└─────────────────────────┘\n",
      "      )\n",
      "    ])\n",
      "  ])\n",
      "])\n"
     ]
    }
   ],
   "source": [
    "params = [a, b]\n",
    "\n",
    "# Define the values to be assigned to the parameters\n",
    "value_dict = {a: np.pi / 4, b: np.pi}\n",
    "\n",
    "# Convert the operator and the gradient target params into the respective operator\n",
    "grad = Gradient().convert(operator = op, params = params)\n",
    "\n",
    "# Print the operator corresponding to the Gradient\n",
    "print(grad)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All that is left to do is to assign values to the parameters and to evaluate the gradient operators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Gradient [(-1.414213562373094+0j), (-0.7071067811865474+0j)]\n"
     ]
    }
   ],
   "source": [
    "# Assign the parameters and evaluate the gradient\n",
    "grad_result = grad.assign_parameters(value_dict).eval()\n",
    "print('Gradient', grad_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Gradients w.r.t. State Parameters\n",
    "\n",
    "Gradient of an expectation value w.r.t. a state $|\\psi\\left(\\theta\\right)\\rangle$ parameter, i.e.$$\\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta} $$\n",
    "respectively of sampling probabilities w.r.t. a state $|\\psi\\left(\\theta\\right)\\rangle$ parameter, i.e.\n",
    "$$ \\frac{\\partial p_i}{\\partial\\theta} = \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|i\\rangle\\langle i |\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta}.$$\n",
    "A gradient w.r.t. a state parameter may be evaluated with different methods. Each method has advantages and disadvantages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ComposedOp([\n",
      "  OperatorMeasurement(0.5 * X\n",
      "  - 1.0 * Z),\n",
      "  CircuitStateFn(\n",
      "        ┌───┐┌───────┐┌───────┐\n",
      "  q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b) ├\n",
      "        └───┘└───────┘└───────┘\n",
      "  )\n",
      "])\n"
     ]
    }
   ],
   "source": [
    "# Define the Hamiltonian with fixed coefficients\n",
    "H = 0.5 * X - 1 * Z\n",
    "# Define the parameters w.r.t. we want to compute the gradients\n",
    "params = [a, b]\n",
    "# Define the values to be assigned to the parameters\n",
    "value_dict = { a: np.pi / 4, b: np.pi}\n",
    "\n",
    "# Combine the Hamiltonian observable and the state into an expectation value operator\n",
    "op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)\n",
    "print(op)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameter Shift Gradients\n",
    "Given a Hermitian operator $g$ with two unique eigenvalues $\\pm r$ which acts as generator for a parameterized quantum gate $$G(\\theta)= e^{-i\\theta g}.$$\n",
    "Then, quantum gradients can be computed by using eigenvalue $r$ dependent shifts to parameters. \n",
    "All [standard, parameterized Qiskit gates](https://github.com/Qiskit/qiskit-terra/tree/master/qiskit/circuit/library/standard_gates) can be shifted with $\\pi/2$, i.e.,\n",
    " $$ \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta} =  \\left(\\langle\\psi\\left(\\theta+\\pi/2\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta+\\pi/2\\right)\\rangle -\\langle\\psi\\left(\\theta-\\pi/2\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta-\\pi/2\\right)\\rangle\\right) / 2.$$\n",
    " Probability gradients are computed equivalently."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ListOp([\n",
      "  SummedOp([\n",
      "    0.25 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└─────────────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.25 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└─────────────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├\n",
      "            └───┘└─────────────────────────┘└───────┘\n",
      "      )\n",
      "    ]),\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌─────────────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├\n",
      "            └───┘└─────────────────────────┘└───────┘\n",
      "      )\n",
      "    ])\n",
      "  ]),\n",
      "  SummedOp([\n",
      "    0.25 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├┤ H ├\n",
      "            └───┘└───────┘└─────────────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.25 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├┤ H ├\n",
      "            └───┘└───────┘└─────────────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├\n",
      "            └───┘└───────┘└─────────────────────────┘\n",
      "      )\n",
      "    ]),\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌─────────────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├\n",
      "            └───┘└───────┘└─────────────────────────┘\n",
      "      )\n",
      "    ])\n",
      "  ])\n",
      "])\n",
      "State gradient computed with parameter shift [(-0.35355339059327356+0j), (0.7071067811865472+0j)]\n"
     ]
    }
   ],
   "source": [
    "# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameters using \n",
    "# the parameter shift method.\n",
    "state_grad = Gradient(grad_method='param_shift').convert(operator=op, params=params)\n",
    "# Print the operator corresponding to the gradient\n",
    "print(state_grad)\n",
    "# Assign the parameters and evaluate the gradient\n",
    "state_grad_result = state_grad.assign_parameters(value_dict).eval()\n",
    "print('State gradient computed with parameter shift', state_grad_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Linear Combination of Unitaries Gradients\n",
    "Unitaries can be written as $U\\left(\\omega\\right) = e^{iM\\left(\\omega\\right)}$, where $M\\left(\\omega\\right)$ denotes a parameterized Hermitian matrix. \n",
    "Further, Hermitian matrices can be decomposed into weighted sums of Pauli terms, i.e., $M\\left(\\omega\\right) = \\sum_pm_p\\left(\\omega\\right)h_p$ with $m_p\\left(\\omega\\right)\\in\\mathbb{R}$ and $h_p=\\bigotimes\\limits_{j=0}^{n-1}\\sigma_{j, p}$ for $\\sigma_{j, p}\\in\\left\\{I, X, Y, Z\\right\\}$ acting on the $j^{\\text{th}}$ qubit. Thus, the gradients of \n",
    "$U_k\\left(\\omega_k\\right)$ are given by\n",
    "\\begin{equation*}\n",
    "\\frac{\\partial U_k\\left(\\omega_k\\right)}{\\partial\\omega_k} = \\sum\\limits_pi \\frac{\\partial m_{k,p}\\left(\\omega_k\\right)}{\\partial\\omega_k}U_k\\left(\\omega_k\\right)h_{k_p}.\n",
    "\\end{equation*}\n",
    "\n",
    "Combining this observation with a circuit structure presented in [Simulating physical phenomena by quantum networks](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.65.042323) allows us to compute the gradient with the evaluation of a single quantum circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ListOp([\n",
      "  SummedOp([\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(ZZ) * 2.0,\n",
      "      CircuitStateFn(\n",
      "             ┌───┐          ┌───────┐┌───────┐┌───┐\n",
      "       q0_0: ┤ H ├────────■─┤ RZ(a) ├┤ RX(b) ├┤ H ├\n",
      "             ├───┤┌─────┐ │ └─┬───┬─┘└───────┘└───┘\n",
      "      q81_0: ┤ H ├┤ SDG ├─■───┤ H ├────────────────\n",
      "             └───┘└─────┘     └───┘                \n",
      "      ) * 0.7071067811865476\n",
      "    ]),\n",
      "    -1.0 * ComposedOp([\n",
      "      OperatorMeasurement(ZZ) * 2.0,\n",
      "      CircuitStateFn(\n",
      "             ┌───┐          ┌───────┐┌───────┐\n",
      "       q0_0: ┤ H ├────────■─┤ RZ(a) ├┤ RX(b) ├\n",
      "             ├───┤┌─────┐ │ └─┬───┬─┘└───────┘\n",
      "      q82_0: ┤ H ├┤ SDG ├─■───┤ H ├───────────\n",
      "             └───┘└─────┘     └───┘           \n",
      "      ) * 0.7071067811865476\n",
      "    ])\n",
      "  ]),\n",
      "  SummedOp([\n",
      "    0.5 * ComposedOp([\n",
      "      OperatorMeasurement(ZZ) * 2.0,\n",
      "      CircuitStateFn(\n",
      "             ┌───┐┌───────┐┌───┐┌───────┐┌───┐\n",
      "       q0_0: ┤ H ├┤ RZ(a) ├┤ X ├┤ RX(b) ├┤ H ├\n",
      "             ├───┤└┬─────┬┘└─┬─┘└─┬───┬─┘└───┘\n",
      "      q83_0: ┤ H ├─┤ SDG ├───■────┤ H ├───────\n",
      "             └───┘ └─────┘        └───┘       \n",
      "      ) * 0.7071067811865476\n",
      "    ]),\n",
      "    -1.0 * ComposedOp([\n",
      "      OperatorMeasurement(ZZ) * 2.0,\n",
      "      CircuitStateFn(\n",
      "             ┌───┐┌───────┐┌───┐┌───────┐\n",
      "       q0_0: ┤ H ├┤ RZ(a) ├┤ X ├┤ RX(b) ├\n",
      "             ├───┤└┬─────┬┘└─┬─┘└─┬───┬─┘\n",
      "      q84_0: ┤ H ├─┤ SDG ├───■────┤ H ├──\n",
      "             └───┘ └─────┘        └───┘  \n",
      "      ) * 0.7071067811865476\n",
      "    ])\n",
      "  ])\n",
      "])\n",
      "State gradient computed with the linear combination method [(-0.3535533905932737+0j), (0.7071067811865472+0j)]\n"
     ]
    }
   ],
   "source": [
    "# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameter using \n",
    "# the linear combination of unitaries method.\n",
    "state_grad = Gradient(grad_method='lin_comb').convert(operator=op, params=params)\n",
    "\n",
    "# Print the operator corresponding to the gradient\n",
    "print(state_grad)\n",
    "\n",
    "# Assign the parameters and evaluate the gradient\n",
    "state_grad_result = state_grad.assign_parameters(value_dict).eval()\n",
    "print('State gradient computed with the linear combination method', state_grad_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Finite Difference Gradients\n",
    "\n",
    "Unlike the other methods, finite difference gradients are numerical estimations rather than analytical values.\n",
    "This implementation employs a central difference approach with $\\epsilon \\ll 1$\n",
    "$$ \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta} \\approx \\frac{1}{2\\epsilon} \\left(\\langle\\psi\\left(\\theta+\\epsilon\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta+\\epsilon\\right)\\rangle - \\partial\\langle\\psi\\left(\\theta-\\epsilon\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta-\\epsilon\\right)\\rangle\\right).$$\n",
    " Probability gradients are computed equivalently."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ListOp([\n",
      "  SummedOp([\n",
      "    250000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.0e-6) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -250000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌────────────────┐┌───────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.0e-6) ├┤ RX(b) ├┤ H ├\n",
      "            └───┘└────────────────┘└───────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -500000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a + 1.0e-6) ├┤ RX(b) ├\n",
      "            └───┘└────────────────┘└───────┘\n",
      "      )\n",
      "    ]),\n",
      "    500000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌────────────────┐┌───────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a - 1.0e-6) ├┤ RX(b) ├\n",
      "            └───┘└────────────────┘└───────┘\n",
      "      )\n",
      "    ])\n",
      "  ]),\n",
      "  SummedOp([\n",
      "    250000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.0e-6) ├┤ H ├\n",
      "            └───┘└───────┘└────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -250000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌────────────────┐┌───┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.0e-6) ├┤ H ├\n",
      "            └───┘└───────┘└────────────────┘└───┘\n",
      "      )\n",
      "    ]),\n",
      "    -500000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.0e-6) ├\n",
      "            └───┘└───────┘└────────────────┘\n",
      "      )\n",
      "    ]),\n",
      "    500000.0 * ComposedOp([\n",
      "      OperatorMeasurement(Z),\n",
      "      CircuitStateFn(\n",
      "            ┌───┐┌───────┐┌────────────────┐\n",
      "      q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.0e-6) ├\n",
      "            └───┘└───────┘└────────────────┘\n",
      "      )\n",
      "    ])\n",
      "  ])\n",
      "])\n",
      "State gradient computed with finite difference [(-0.35355339057345814+0j), (0.707106781149+0j)]\n"
     ]
    }
   ],
   "source": [
    "# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameter using \n",
    "# the finite difference method.\n",
    "state_grad = Gradient(grad_method='fin_diff').convert(operator=op, params=params)\n",
    "\n",
    "# Print the operator corresponding to the gradient\n",
    "print(state_grad)\n",
    "\n",
    "# Assign the parameters and evaluate the gradient\n",
    "state_grad_result = state_grad.assign_parameters(value_dict).eval()\n",
    "print('State gradient computed with finite difference', state_grad_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Natural Gradient\n",
    "\n",
    "A special type of first order gradient is the natural gradient which has proven itself useful in classical machine learning and is already being studied in the quantum context. This quantity represents a gradient that is 'rescaled' with the inverse [Quantum Fisher Information matrix](#Quantum-Fisher-Information-(QFI)) (QFI)\n",
    "$$ QFI ^{-1} \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta}.$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "Instead of inverting the QFI, one can also use a least-square solver with or without regularization to solve\n",
    "\n",
    "$$ QFI x = \\frac{\\partial\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta}.$$\n",
    "\n",
    "The implementation supports ridge and lasso regularization with automatic search for a good parameter using [L-curve corner search](https://arxiv.org/pdf/1608.04571.pdf) as well as two types of perturbations of the diagonal elements of the QFI.\n",
    "\n",
    "The natural gradient can be used instead of the standard gradient with any gradient-based optimizer and/or ODE solver."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Natural gradient computed with linear combination of unitaries [-2.62895551  1.31447775]\n"
     ]
    }
   ],
   "source": [
    "# Besides the method to compute the circuit gradients resp. QFI, a regularization method can be chosen: \n",
    "# `ridge` or `lasso` with automatic parameter search or `perturb_diag_elements` or `perturb_diag` \n",
    "# which perturb the diagonal elements of the QFI.\n",
    "nat_grad = NaturalGradient(grad_method='lin_comb', qfi_method='lin_comb_full', regularization='ridge').convert(\n",
    "                           operator=op, params=params)\n",
    "\n",
    "# Assign the parameters and evaluate the gradient\n",
    "nat_grad_result = nat_grad.assign_parameters(value_dict).eval()\n",
    "print('Natural gradient computed with linear combination of unitaries', nat_grad_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Hessians (Second Order Gradients)\n",
    "\n",
    "Four types of second order gradients are supported by the gradient framework.\n",
    "\n",
    "1. Gradient of an expectation value w.r.t. a coefficient of the measurement operator respectively observable $\\hat{O}\\left(\\omega\\right)$, i.e.\n",
    "$\\frac{\\partial^2\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\omega^2}$\n",
    "2. Gradient of an expectation value w.r.t. a state $|\\psi\\left(\\theta\\right)\\rangle$ parameter, i.e.\n",
    "$\\frac{\\partial^2\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta^2}$\n",
    "3. Gradient of sampling probabilities w.r.t. a state $|\\psi\\left(\\theta\\right)\\rangle$ parameter, i.e.\n",
    "$\\frac{\\partial^2 p_i}{\\partial\\theta^2} = \\frac{\\partial^2\\langle\\psi\\left(\\theta\\right)|i\\rangle\\langle i|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta^2}$\n",
    "4. Gradient of an expectation value w.r.t. a state $|\\psi\\left(\\theta\\right)\\rangle$ parameter and a coefficient of the measurement operator respectively observable $\\hat{O}\\left(\\omega\\right)$, i.e.\n",
    "$\\frac{\\partial^2\\langle\\psi\\left(\\theta\\right)|\\hat{O}\\left(\\omega\\right)|\\psi\\left(\\theta\\right)\\rangle}{\\partial\\theta\\partial\\omega}$\n",
    "\n",
    "In the following examples are given for the first two Hessian types. The remaining Hessians are evaluated analogously."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Hessians w.r.t. Measurement Operator Parameters\n",
    "\n",
    "Again, we define a quantum state $|\\psi\\left(\\theta\\right)\\rangle$ and a Hamiltonian $H$ acting as observable. Then, the state and the Hamiltonian are wrapped into an object defining the expectation value $$ \\langle\\psi\\left(\\theta\\right)|H|\\psi\\left(\\theta\\right)\\rangle. $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "# Instantiate the Hamiltonian observable\n",
    "H = X\n",
    "\n",
    "# Instantiate the quantum state with two parameters\n",
    "a = Parameter('a')\n",
    "b = Parameter('b')\n",
    "\n",
    "q = QuantumRegister(1)\n",
    "qc = QuantumCircuit(q)\n",
    "qc.h(q)\n",
    "qc.rz(a, q[0])\n",
    "qc.rx(b, q[0])\n",
    "\n",
    "# Combine the Hamiltonian observable and the state\n",
    "op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we can choose the parameters for which we want to compute second order gradients.\n",
    "- Given a tuple, the `Hessian` will evaluate the second order gradient for the two parameters. \n",
    "- Given a list, the `Hessian` will evaluate the second order gradient for all possible combinations of tuples of these parameters.\n",
    "\n",
    "After binding parameter values to the parameters, the Hessian can be evaluated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hessian \n",
      " [[-7.07106781e-01  0.00000000e+00]\n",
      " [ 0.00000000e+00 -5.55111512e-17]]\n"
     ]
    }
   ],
   "source": [
    "# Convert the operator and the hessian target coefficients into the respective operator\n",
    "hessian = Hessian().convert(operator = op, params = [a, b])\n",
    "\n",
    "# Define the values to be assigned to the parameters\n",
    "value_dict = {a: np.pi / 4, b: np.pi/4}\n",
    "\n",
    "# Assign the parameters and evaluate the Hessian w.r.t. the Hamiltonian coefficients\n",
    "hessian_result = hessian.assign_parameters(value_dict).eval()\n",
    "print('Hessian \\n', np.real(np.array(hessian_result)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Hessians w.r.t. State Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hessian computed using the parameter shift method\n",
      " [[-7.07106781e-01+0.j  0.00000000e+00+0.j]\n",
      " [ 0.00000000e+00+0.j -5.55111512e-17+0.j]]\n",
      "Hessian computed using the linear combination of unitaries method\n",
      " [[-7.07106781e-01+0.j  0.00000000e+00+0.j]\n",
      " [ 0.00000000e+00+0.j  5.60000000e-17+0.j]]\n",
      "Hessian computed with finite difference\n",
      " [[-7.07122803e-01+0.j  3.05175781e-05+0.j]\n",
      " [ 3.05175781e-05+0.j -6.10351562e-05+0.j]]\n"
     ]
    }
   ],
   "source": [
    "# Define parameters\n",
    "params = [a, b]\n",
    "\n",
    "# Get the operator object representing the Hessian\n",
    "state_hess = Hessian(hess_method='param_shift').convert(operator=op, params=params)\n",
    "# Assign the parameters and evaluate the Hessian\n",
    "hessian_result = state_hess.assign_parameters(value_dict).eval()\n",
    "print('Hessian computed using the parameter shift method\\n', (np.array(hessian_result)))\n",
    "\n",
    "# Get the operator object representing the Hessian\n",
    "state_hess = Hessian(hess_method='lin_comb').convert(operator=op, params=params)\n",
    "# Assign the parameters and evaluate the Hessian\n",
    "hessian_result = state_hess.assign_parameters(value_dict).eval()\n",
    "print('Hessian computed using the linear combination of unitaries method\\n', (np.array(hessian_result)))\n",
    "\n",
    "# Get the operator object representing the Hessian using finite difference\n",
    "state_hess = Hessian(hess_method='fin_diff').convert(operator=op, params=params)\n",
    "# Assign the parameters and evaluate the Hessian\n",
    "hessian_result = state_hess.assign_parameters(value_dict).eval()\n",
    "print('Hessian computed with finite difference\\n', (np.array(hessian_result)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Quantum Fisher Information (QFI)\n",
    "The Quantum Fisher Information is a metric tensor which is representative for the representation capacity of a \n",
    "parameterized quantum state $|\\psi\\left(\\theta\\right)\\rangle = V\\left(\\theta\\right)|\\psi\\rangle$ with input state $|\\psi\\rangle$, parametrized Ansatz $V\\left(\\theta\\right)$.\n",
    "\n",
    "The entries of the QFI for a pure state reads\n",
    "\n",
    "$$QFI_{kl} = 4 * \\text{Re}\\left[\\langle\\partial_k\\psi|\\partial_l\\psi\\rangle-\\langle\\partial_k\\psi|\\psi\\rangle\\langle\\psi|\\partial_l\\psi\\rangle \\right].$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Circuit QFIs\n",
    "\n",
    "The evaluation of the QFI corresponding to a quantum state that is generated by a parameterized quantum circuit can be conducted in different ways.\n",
    "\n",
    "### Linear Combination Full QFI\n",
    "To compute the full QFI, we use a working qubit as well as intercepting controlled gates. See e.g. [Variational ansatz-based quantum simulation of imaginary time evolution ](https://www.nature.com/articles/s41534-019-0187-2)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "full QFI \n",
      " [[ 1.0000000e+00 -2.0659798e-16]\n",
      " [-2.0659798e-16  5.0000000e-01]]\n"
     ]
    }
   ],
   "source": [
    "# Wrap the quantum circuit into a CircuitStateFn\n",
    "state = CircuitStateFn(primitive=qc, coeff=1.)\n",
    "\n",
    "# Convert the state and the parameters into the operator object that represents the QFI \n",
    "qfi = QFI(qfi_method='lin_comb_full').convert(operator=state, params=params)\n",
    "# Define the values for which the QFI is to be computed\n",
    "values_dict = {a: np.pi / 4, b: 0.1}\n",
    "\n",
    "# Assign the parameters and evaluate the QFI\n",
    "qfi_result = qfi.assign_parameters(values_dict).eval()\n",
    "print('full QFI \\n', np.real(np.array(qfi_result)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Block-diagonal and Diagonal Approximation\n",
    "A block-diagonal resp. diagonal approximation of the QFI can be computed without additional working qubits.\n",
    "This implementation requires the unrolling into Pauli rotations and unparameterized Gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Block-diagonal QFI \n",
      " [[1.  0. ]\n",
      " [0.  0.5]]\n",
      "Diagonal QFI \n",
      " [[1.  0. ]\n",
      " [0.  0.5]]\n"
     ]
    }
   ],
   "source": [
    "# Convert the state and the parameters into the operator object that represents the QFI \n",
    "# and set the approximation to 'block_diagonal'\n",
    "qfi = QFI('overlap_block_diag').convert(operator=state, params=params)\n",
    "\n",
    "# Assign the parameters and evaluate the QFI\n",
    "qfi_result = qfi.assign_parameters(values_dict).eval()\n",
    "print('Block-diagonal QFI \\n', np.real(np.array(qfi_result)))\n",
    "\n",
    "# Convert the state and the parameters into the operator object that represents the QFI \n",
    "# and set the approximation to 'diagonal'\n",
    "qfi = QFI('overlap_diag').convert(operator=state, params=params)\n",
    "\n",
    "# Assign the parameters and evaluate the QFI\n",
    "qfi_result = qfi.assign_parameters(values_dict).eval()\n",
    "print('Diagonal QFI \\n', np.real(np.array(qfi_result)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Application Example: VQE with gradient-based optimization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Additional Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Execution Imports\n",
    "from qiskit import Aer\n",
    "from qiskit.utils import QuantumInstance\n",
    "\n",
    "# Algorithm Imports\n",
    "from qiskit.algorithms import VQE\n",
    "from qiskit.algorithms.optimizers import CG"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "The Gradient Framework can also be used for a gradient-based `VQE`.\n",
    "First, the Hamiltonian and wavefunction ansatz are initialized."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit.opflow import I, X, Z\n",
    "from qiskit.circuit import QuantumCircuit, ParameterVector\n",
    "from scipy.optimize import minimize\n",
    "\n",
    "# Instantiate the system Hamiltonian\n",
    "h2_hamiltonian = -1.05 * (I ^ I) + 0.39 * (I ^ Z) - 0.39 * (Z ^ I) - 0.01 * (Z ^ Z) + 0.18 * (X ^ X)\n",
    "\n",
    "# This is the target energy\n",
    "h2_energy = -1.85727503\n",
    "\n",
    "# Define the Ansatz\n",
    "wavefunction = QuantumCircuit(2)\n",
    "params = ParameterVector('theta', length=8)\n",
    "it = iter(params)\n",
    "wavefunction.ry(next(it), 0)\n",
    "wavefunction.ry(next(it), 1)\n",
    "wavefunction.rz(next(it), 0)\n",
    "wavefunction.rz(next(it), 1)\n",
    "wavefunction.cx(0, 1)\n",
    "wavefunction.ry(next(it), 0)\n",
    "wavefunction.ry(next(it), 1)\n",
    "wavefunction.rz(next(it), 0)\n",
    "wavefunction.rz(next(it), 1)\n",
    "\n",
    "# Define the expectation value corresponding to the energy\n",
    "op = ~StateFn(h2_hamiltonian) @ StateFn(wavefunction)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we can choose whether the `VQE` should use a `Gradient` or `NaturalGradient`, define a `QuantumInstance` to execute the quantum circuits and run the algorithm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Result: -0.8800000000000001 Reference: -1.85727503\n"
     ]
    }
   ],
   "source": [
    "grad = Gradient(grad_method='lin_comb')\n",
    "\n",
    "qi_sv = QuantumInstance(Aer.get_backend('aer_simulator_statevector'),\n",
    "                        shots=1,\n",
    "                        seed_simulator=2,\n",
    "                        seed_transpiler=2)\n",
    "\n",
    "#Conjugate Gradient algorithm\n",
    "optimizer = CG(maxiter=50)\n",
    "\n",
    "# Gradient callable\n",
    "vqe = VQE(wavefunction, optimizer=optimizer, gradient=grad, quantum_instance=qi_sv)\n",
    "\n",
    "result = vqe.compute_minimum_eigenvalue(h2_hamiltonian)\n",
    "print('Result:', result.optimal_value, 'Reference:', h2_energy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h3>Version Information</h3><table><tr><th>Qiskit Software</th><th>Version</th></tr><tr><td>Qiskit</td><td>None</td></tr><tr><td>Terra</td><td>0.17.4</td></tr><tr><td>Aer</td><td>0.8.2</td></tr><tr><td>Ignis</td><td>None</td></tr><tr><td>Aqua</td><td>None</td></tr><tr><td>IBM Q Provider</td><td>None</td></tr><tr><th>System information</th></tr><tr><td>Python</td><td>3.8.8 (default, Apr 13 2021, 12:59:45) \n",
       "[Clang 10.0.0 ]</td></tr><tr><td>OS</td><td>Darwin</td></tr><tr><td>CPUs</td><td>2</td></tr><tr><td>Memory (Gb)</td><td>12.0</td></tr><tr><td colspan='2'>Fri May 28 09:42:47 2021 EDT</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style='width: 100%; background-color:#d5d9e0;padding-left: 10px; padding-bottom: 10px; padding-right: 10px; padding-top: 5px'><h3>This code is a part of Qiskit</h3><p>&copy; Copyright IBM 2017, 2021.</p><p>This code is licensed under the Apache License, Version 2.0. You may<br>obtain a copy of this license in the LICENSE.txt file in the root directory<br> of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.<p>Any modifications or derivative works of this code must retain this<br>copyright notice, and modified files need to carry a notice indicating<br>that they have been altered from the originals.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import qiskit.tools.jupyter\n",
    "%qiskit_version_table\n",
    "%qiskit_copyright"
   ]
  }
 
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
